<?php

if (!defined('PHOX') or !constant('PHOX')) die('Direct access not allowed!');

/**
 * Object_Registry 
 *
 * Stores and fetches objects, an efficient mechanism to aplly the Singleton
 * Pattern to all classes we need 
 * 
 * @package lib
 * @version 0.1
 * @author Pedro Eugénio <voxmachina@sapo.pt> 
 * @license GPL v.3
 */
class Object_Registry
{
    private static $list      = array();  // an array of objects
    private static $instance;

    // protect direct and clone access
    private function __construct() {}
    private function __clone() {}

   /**
    * singleton 
    *
    * Method used to access an object
    * 
    * @return Object singleton instance
    */
    public static function singleton()
    {
      if( !isset( self::$instance ) )
      {
        self::$instance = new self();
      }
      return self::$instance;
    }

   /**
    * get 
    * 
    * Returns stored object given an identifier key
    * 
    * @param mixed $k , a key
    * @return Object
    */
    protected function get($k)
    {
      if( isset( $this->list[$k] ) )
      {
        return $this->list[$k];
      } else {
        return NULL;
      }
    }
    
   /**
    * set 
    * 
    * Stores an object, given its key and value
    * 
    * @param mixed $k , a key
    * @param mixed $v , a value
    * @return void
    */
    protected function set($k,$v)
    {
      $this->list[$k] = $v;
    }

   /**
    * getObject
    *
    * Object request handler 
    * 
    * @param mixed $k , the object key identifier
    * @return Object
    */
    public static function getObject($k)
    {
      return self::singleton()->get($k);
    }

   /**
    * setObject 
    *
    * Store object handler
    * 
    * @param mixed $k , object key identifier
    * @param mixed $i , instance to associate
    * @return void
    */
    public static function setObject($k,$i)
    {
      return self::singleton()->set($k,$i);
    }
} // end class

/**
 * register 
 *
 * Registry controller function
 * 
 * @param mixed $class, class name to register 
 * @access public
 * @return void
 */
function register($class)
{
    $obj        = Object_Registry::singleton();
    $class      = strtolower( $class );
  
    // check to see if its allready stored
    if( $obj->getObject( $class ) !== NULL )
    {
      return $obj->getObject( $class );
    }

    // extension
    $coreFile = ROOT_DIR.SEPARATOR.BASE.SEPARATOR.BASELIB.SEPARATOR.ucfirst($class).EXTENSION;
    $extFile  = ROOT_DIR.SEPARATOR.APP.SEPARATOR.APPLIB.SEPARATOR.ucfirst($class).EXTENSION;
    $viewFile = ROOT_DIR.SEPARATOR.APP.SEPARATOR.VIEWLIB.SEPARATOR.ucfirst($class).EXTENSION;
    $contFile = ROOT_DIR.SEPARATOR.APP.SEPARATOR.CONTLIB.SEPARATOR.ucfirst($class).EXTENSION;

    if( file_exists( $coreFile ) )
    {
      require( $coreFile );
    } else if( file_exists( $extFile ) ) {
      require( $extFile );
    } else if( file_exists( $viewFile ) ) {
      require( $viewFile );
    } else if( file_exists( $contFile ) ) {
      require( $contFile );
    }
 
    $caller     = ucfirst( $class );
    $obj->setObject( $class , new $caller() );
    $theObject  = $obj->getObject( $class );
    
    if( is_object( $theObject ) )
    {
      return $theObject;
    }
}

?>
